home *** CD-ROM | disk | FTP | other *** search
- #define ALL
-
- #include "common.h"
- #include "defs.h"
- #include <proto/mathieeedoubbas.h>
- #include <proto/mathieeedoubtrans.h>
- #include <proto/mathieeesingbas.h>
-
- /* Special patch to work around bug in IEEEDPCmp:
- * if the first 32 bits of both doubles are equal, and
- * both doubles are negative, then the result can no longer
- * be trusted.
- *
- * This is the output of a small test program:
- *
- * test -2.000001 -2.0000009
- * a = -2.0000009999999996956888, b = -2.0000008999999998593466
- * (0xc0000000 0x8637bd05, 0xc0000000 0x78cbc3b8)
- * cmp(a,b) = 0, cmp(b,a) = 1
- *
- * test -2.0000001 -2.0000002
- * a = -2.00000009999999983634211, b = -2.0000001999999996726842
- * (0xc0000000 0xd6bf94d, 0xc0000000 0x1ad7f29a)
- * cmp(a,b) = 1, cmp(b,a) = 1
- *
- * As you can see, the results are wrong.
- *
- * So, we just make both variables positive and exchange them before
- * passing them to IEEEDPCmp.
- *
- * This bug was discovered by Bart Van Assche, thanks!
- */
-
- static int ieeedpcmp(double a, double b)
- {
- if (*((char *)&a) & *((char *)&b) & 0x80) /* both doubles negative? */
- {
- *((char *)&a) &= 0x7f; /* yes, make positive */
- *((char *)&b) &= 0x7f;
- return IEEEDPCmp(b, a); /* pass them to IEEEDPCmp the other way round */
- }
- return IEEEDPCmp(a, b);
- }
-
- #if defined(L__eqdf2) || defined(ALL)
- int __eqdf2 (double a, double b)
- {
- return ieeedpcmp (a, b);
- }
- #endif
-
- #if defined(L__eqsf2) || defined(ALL)
- int __eqsf2 (FLOAT a, FLOAT b)
- {
- return IEEESPCmp (a, b);
- }
- #endif
-
- #if defined(L__fixsfsi) || defined(ALL)
- SItype __fixsfsi (FLOAT a)
- {
- return IEEESPFix(a);
- }
- #endif
-
- #if defined(L__floatsisf) || defined(ALL)
- SFVALUE __floatsisf (SItype a)
- {
- return IEEESPFlt(a);
- }
- #endif
-
- #if defined(L__gedf2) || defined(ALL)
- int __gedf2 (double a, double b)
- {
- return ieeedpcmp (a, b);
- }
- #endif
-
- #if defined(L__gesf2) || defined(ALL)
- int __gesf2 (FLOAT a, FLOAT b)
- {
- return IEEESPCmp (a, b);
- }
- #endif
-
- #if defined(L__gtdf2) || defined(ALL)
- int __gtdf2 (double a, double b)
- {
- return ieeedpcmp (a, b);
- }
- #endif
-
- #if defined(L__gtsf2) || defined(ALL)
- int __gtsf2 (FLOAT a, FLOAT b)
- {
- return IEEESPCmp (a, b);
- }
- #endif
-
- #if defined(L__ledf2) || defined(ALL)
- int __ledf2 (double a, double b)
- {
- return ieeedpcmp (a, b);
- }
- #endif
-
- #if defined(L__lesf2) || defined(ALL)
- int __lesf2 (FLOAT a, FLOAT b)
- {
- return IEEESPCmp (a, b);
- }
- #endif
-
- #if defined(L__ltdf2) || defined(ALL)
- int __ltdf2 (double a, double b)
- {
- return ieeedpcmp (a, b);
- }
- #endif
-
- #if defined(L__ltsf2) || defined(ALL)
- int __ltsf2 (FLOAT a, FLOAT b)
- {
- return IEEESPCmp (a, b);
- }
- #endif
-
- #if defined(L__nedf2) || defined(ALL)
- int __nedf2 (double a, double b)
- {
- return !!ieeedpcmp (a, b);
- }
- #endif
-
- #if defined(L__nesf2) || defined(ALL)
- int __nesf2 (FLOAT a, FLOAT b)
- {
- return !!IEEESPCmp (a, b);
- }
- #endif
-
-
-
-
- #if defined (mc68020) || defined (mc68030) || defined (mc68040) || defined (mc68060)
-
- /* int / int */
- #if defined(L__divsi3) || defined(ALL)
- ENTRY(__divsi3)
- asm("
- movel sp@(4),d0
- divsl sp@(8),d0
- rts
- ");
- #endif
-
- /* int % int */
- #if defined(L__modsi3) || defined(ALL)
- ENTRY(__modsi3)
- asm("
- movel sp@(4),d1
- divsll sp@(8),d0:d1
- rts
- ");
- #endif
-
- /* int * int */
- #if defined(L__mulsi3) || defined(ALL)
- ENTRY(__mulsi3)
- asm("
- movel sp@(4),d0
- mulsl sp@(8),d0
- rts
- ");
- #endif
-
- /* unsigned / unsigned */
- #if defined(L__udivsi3) || defined(ALL)
- ENTRY(__udivsi3)
- asm("
- movel sp@(4),d0
- divul sp@(8),d0
- rts
- ");
- #endif
-
- /* unsigned % unsigned */
- #if defined(L__umodsi3) || defined(ALL)
- ENTRY(__umodsi3)
- asm("
- movel sp@(4),d1
- divull sp@(8),d0:d1
- rts
- ");
- #endif
-
- /* unsigned * unsigned */
- #if defined(L__umulsi3) || defined(ALL)
- ENTRY(__umulsi3)
- asm("
- movel sp@(4),d0
- mulul sp@(8),d0
- rts
- ");
- #endif
-
-
- #else
-
-
- #if defined(L__divsi3) || defined(ALL)
- SItype __divsi3 (SItype a, SItype b)
- {
- unsigned SItype q, r;
- int neg = (a < 0) != (b < 0);
-
- if (a < 0) a = -a;
- if (b < 0) b = -b;
-
- divmodu (q, r, a, b);
-
- return neg ? -q : q;
- }
- #endif
-
- #if defined(L__modsi3) || defined(ALL)
- SItype __modsi3 (SItype a, SItype b)
- {
- unsigned SItype q, r;
- int neg = (a < 0);
-
- if (a < 0) a = -a;
- if (b < 0) b = -b;
-
- divmodu (q, r, a, b);
-
- return neg ? -r : r;
- }
- #endif
-
- #if defined(L__mulsi3) || defined(ALL)
- SItype __mulsi3 (SItype a, SItype b)
- {
- int neg = (a < 0) != (b < 0);
- SItype res;
-
- if (a < 0) a = -a;
- if (b < 0) b = -b;
-
- res = mulu (a,b);
- return neg ? -res : res;
- }
- #endif
-
- #if defined(L__udivsi3) || defined(ALL)
- unsigned SItype __udivsi3 (unsigned SItype a, unsigned SItype b)
- {
- unsigned SItype q, r;
- divmodu (q, r, a, b);
- return q;
- }
- #endif
-
- #if defined(L__umodsi3) || defined(ALL)
- unsigned SItype __umodsi3 (unsigned SItype a, unsigned SItype b)
- {
- unsigned SItype q, r;
- divmodu (q, r, a, b);
- return r;
- }
- #endif
-
- #endif
-
- /* -double */
- #if defined(L__negdf2) || defined(ALL)
- ENTRY(__negdf2)
- asm("
- movel sp@(4),d0
- movel sp@(8),d1
- bchg #31,d0
- rts
- ");
- #endif
-
- /* -single */
- #if defined(L__negsf2) || defined(ALL)
- ENTRY(__negsf2)
- asm("
- movel sp@(4),d0
- bchg #31,d0
- rts
- ");
- #endif
-
-
-
- #ifdef __HAVE_68881__
-
- /* double + double */
- #if defined(L__adddf3) || defined(ALL)
- ENTRY(__adddf3)
- asm("
- fmoved sp@(4),fp0
- faddd sp@(12),fp0
- fmoved fp0,sp@-
- movel sp@+,d0
- movel sp@+,d1
- rts
- ");
- #endif
-
- /* single + single */
- #if defined(L__addsf3) || defined(ALL)
- ENTRY(__addsf3)
- asm("
- fmoves sp@(4),fp0
- fadds sp@(8),fp0
- fmoves fp0,d0
- rts
- ");
- #endif
-
- /* double > double: 1 */
- /* double < double: -1 */
- /* double == double: 0 */
- #if defined(L__cmpdf2) || defined(ALL)
- ENTRY(__cmpdf2)
- asm("
- fmoved sp@(4),fp0
- fcmpd sp@(12),fp0
- fbgt Lagtb1
- fslt d0
- extbl d0
- rts
- Lagtb1:
- moveq #1,d0
- rts
- ");
- #endif
-
- /* single > single: 1 */
- /* single < single: -1 */
- /* single == single: 0 */
- #if defined(L__cmpsf2) || defined(ALL)
- ENTRY(__cmpsf2)
- asm("
- fmoves sp@(4),fp0
- fcmps sp@(8),fp0
- fbgt Lagtb2
- fslt d0
- extbl d0
- rts
- Lagtb2:
- moveq #1,d0
- rts
- ");
- #endif
-
- /* double / double */
- #if defined(L__divdf3) || defined(ALL)
- ENTRY(__divdf3)
- asm("
- fmoved sp@(4),fp0
- fdivd sp@(12),fp0
- fmoved fp0,sp@-
- movel sp@+,d0
- movel sp@+,d1
- rts
- ");
- #endif
-
- /* single / single */
- #if defined(L__divsf3) || defined(ALL)
- ENTRY(__divsf3)
- asm("
- fmoves sp@(4),fp0
- fdivs sp@(8),fp0
- fmoves fp0,d0
- rts
- ");
- #endif
-
- /* (double) float */
- #if defined(L__extendsfdf2) || defined(ALL)
- ENTRY(__extendsfdf2)
- asm("
- fmoves sp@(4),fp0
- fmoved fp0,sp@-
- movel sp@+,d0
- movel sp@+,d1
- rts
- ");
- #endif
-
- #if defined(Lfabs) || defined(ALL)
- ENTRY(fabs)
- asm("
- fmoved sp@(4),fp0
- fjnlt L1
- fnegx fp0
- L1:
- fmoved fp0,sp@-
- movel sp@+,d0
- movel sp@+,d1
- rts
- ");
- #endif
-
- /* (int) double */
- #if defined(L__fixdfsi) || defined(ALL)
- ENTRY(__fixdfsi)
- asm("
- fintrzd sp@(4),fp0
- fmovel fp0,d0
- rts
- ");
- #endif
-
- /* (double) int */
- #if defined(L__floatsidf) || defined(ALL)
- ENTRY(__floatsidf)
- asm("
- fmovel sp@(4),fp0
- fmoved fp0,sp@-
- movel sp@+,d0
- movel sp@+,d1
- rts
- ");
- #endif
-
- /*
- * double frexp(val, eptr)
- * returns: x s.t. val = x * (2 ** n), with n stored in *eptr
- */
- #if defined(Lfrexp) || defined(ALL)
- ENTRY(frexp)
- asm("
- fmoved sp@(4),fp1
- fgetmanx fp1,fp0
- fgetexpx fp1
- fmovel fp1,d0
- addql #1,d0
- movel sp@(12),a0
- movel d0,a0@
- fdivl #2,fp0
- fmoved fp0,sp@-
- movel sp@+,d0
- movel sp@+,d1
- rts
- ");
- #endif
-
- /*
- * double ldexp(val, exp)
- * returns: val * (2**exp), for integer exp
- */
- #if defined(Lldexp) || defined(ALL)
- ENTRY(ldexp)
- asm("
- fmoved sp@(4),fp0
- fbeq Ldone
- ftwotoxl sp@(12),fp1
- fmulx fp1,fp0
- Ldone:
- fmoved fp0,sp@-
- movel sp@+,d0
- movel sp@+,d1
- rts
- ");
- #endif
-
- /*
- * double modf(val, iptr)
- * returns: xxx and n (in *iptr) where val == n.xxx
- */
- #if defined(Lmodf) || defined(ALL)
- ENTRY(modf)
- asm("
- fmoved sp@(4),fp0
- movel sp@(12),a0
- fintrzx fp0,fp1
- fmoved fp1,a0@
- fsubx fp1,fp0
- fmoved fp0,sp@-
- movel sp@+,d0
- movel sp@+,d1
- rts
- ");
- #endif
-
- /* double * double */
- #if defined(L__muldf3) || defined(ALL)
- ENTRY(__muldf3)
- asm("
- fmoved sp@(4),fp0
- fmuld sp@(12),fp0
- fmoved fp0,sp@-
- movel sp@+,d0
- movel sp@+,d1
- rts
- ");
- #endif
-
- /* single * single */
- #if defined(L__mulsf3) || defined(ALL)
- ENTRY(__mulsf3)
- asm("
- fmoves sp@(4),fp0
- fmuls sp@(8),fp0
- fmoves fp0,d0
- rts
- ");
- #endif
-
- /* double - double */
- #if defined(L__subdf3) || defined(ALL)
- ENTRY(__subdf3)
- asm("
- fmoved sp@(4),fp0
- fsubd sp@(12),fp0
- fmoved fp0,sp@-
- movel sp@+,d0
- movel sp@+,d1
- rts
- ");
- #endif
-
- /* single - single */
- #if defined(L__subsf3) || defined(ALL)
- ENTRY(__subsf3)
- asm("
- fmoves sp@(4),fp0
- fsubs sp@(8),fp0
- fmoves fp0,d0
- rts
- ");
- #endif
-
- /* (float) double */
- #if defined(L__truncdfsf2) || defined(ALL)
- ENTRY(__truncdfsf2)
- asm("
- fmoved sp@(4),fp0
- fmoves fp0,d0
- rts
- ");
- #endif
-
- #else /* __HAVE_68881__ */
-
- #if defined(L__adddf3) || defined(ALL)
- double __adddf3 (double a, double b)
- {
- return IEEEDPAdd (a, b);
- }
- #endif
-
- #if defined(L__addsf3) || defined(ALL)
- SFVALUE __addsf3 (FLOAT a, FLOAT b)
- {
- return IEEESPAdd (a, b);
- }
- #endif
-
- #if defined(L__cmpdf2) || defined(ALL)
- int __cmpdf2 (double a, double b)
- {
- return ieeedpcmp (a, b);
- }
- #endif
-
- #if defined(L__cmpsf2) || defined(ALL)
- int __cmpsf2 (FLOAT a, FLOAT b)
- {
- return IEEESPCmp (a, b);
- }
- #endif
-
- #if defined(L__divdf3) || defined(ALL)
- double __divdf3 (double a, double b)
- {
- return IEEEDPDiv (a, b);
- }
- #endif
-
- #if defined(L__divsf3) || defined(ALL)
- SFVALUE __divsf3 (FLOAT a, FLOAT b)
- {
- return IEEESPDiv (a, b);
- }
- #endif
-
- #if defined(L__extendsfdf2) || defined(ALL)
- double __extendsfdf2 (FLOAT a)
- {
- return IEEEDPFieee(a);
- }
- #endif
-
- #if defined(Lfabs) || defined(ALL)
- double fabs (double d)
- {
- return d < 0.0 ? -d : d;
- }
- #endif
-
- #if defined(L__fixdfsi) || defined(ALL)
- SItype __fixdfsi (double a)
- {
- return IEEEDPFix (a);
- }
- #endif
-
- #if defined(L__floatsidf) || defined(ALL)
- double __floatsidf (SItype a)
- {
- return IEEEDPFlt (a);
- }
- #endif
-
- /*
- * the call
- * x = frexp(arg,&exp);
- * must return a double fp quantity x which is <1.0
- * and the corresponding binary exponent "exp".
- * such that
- * arg = x*2^exp
- * if the argument is 0.0, return 0.0 mantissa and 0 exponent.
- */
-
- #if defined(Lfrexp) || defined(ALL)
- double frexp (double x, int *i)
- {
- int neg = 0;
- int j = 0;
-
- if (x < 0)
- {
- x = -x;
- neg = 1;
- }
-
- if (x >= 1.0)
- while (x >= 1.0)
- {
- j = j + 1;
- x = x / 2;
- }
- else if (x < 0.5 && x != 0.0)
- while (x < 0.5)
- {
- j = j - 1;
- x = 2 * x;
- }
-
- *i = j;
- if (neg)
- x = -x;
- return x;
- }
- #endif
-
- #if defined(Lldexp) || defined(ALL)
- /*
- * ldexp returns the quanity "value" * 2 ^ "exp"
- *
- * For the mc68000 using IEEE format the double precision word format is:
- *
- * WORD N => SEEEEEEEEEEEMMMM
- * WORD N+1 => MMMMMMMMMMMMMMMM
- * WORD N+2 => MMMMMMMMMMMMMMMM
- * WORD N+3 => MMMMMMMMMMMMMMMM
- *
- * Where: S => Sign bit
- * E => Exponent
- * X => Ignored (set to 0)
- * M => Mantissa bit
- *
- * NOTE: Beware of 0.0; on some machines which use excess 128 notation for the
- * exponent, if the mantissa is zero the exponent is also.
- *
- */
-
- #define MANT_MASK 0x800FFFFF /* Mantissa extraction mask */
- #define ZPOS_MASK 0x3FF00000 /* Positive # mask for exp = 0 */
- #define ZNEG_MASK 0x3FF00000 /* Negative # mask for exp = 0 */
-
- #define EXP_MASK 0x7FF00000 /* Mask for exponent */
- #define EXP_SHIFTS 20 /* Shifts to get into LSB's */
- #define EXP_BIAS 1023 /* Exponent bias */
-
- union dtol
- {
- double dval;
- int ival[2];
- };
-
- double ldexp (double value, int exp)
- {
- union dtol number;
- int *iptr, cexp;
-
- if (value == 0.0)
- return (0.0);
- number.dval = value;
- iptr = &number.ival[0];
- cexp = (((*iptr) & EXP_MASK) >> EXP_SHIFTS) - EXP_BIAS;
- *iptr &= ~EXP_MASK;
- exp += EXP_BIAS;
- *iptr |= ((exp + cexp) << EXP_SHIFTS) & EXP_MASK;
- return (number.dval);
- }
- #endif
-
- /*
- * modf(value, iptr): return fractional part of value, and stores the
- * integral part into iptr (a pointer to double).
- */
-
- #if defined(Lmodf) || defined(ALL)
- double modf (double value, double *iptr)
- {
- /* if value negative */
- if (IEEEDPTst (value) < 0)
- {
- /* in that case, the integer part is calculated by ceil() */
- *iptr = IEEEDPCeil (value);
- return IEEEDPSub (*iptr, value);
- }
- else
- {
- /* if positive, we go for the floor() */
- *iptr = IEEEDPFloor (value);
- return IEEEDPSub (value, *iptr);
- }
- }
- #endif
-
- #if defined(L__muldf3) || defined(ALL)
- double __muldf3 (double a, double b)
- {
- return IEEEDPMul (a, b);
- }
- #endif
-
- #if defined(L__mulsf3) || defined(ALL)
- SFVALUE __mulsf3 (FLOAT a, FLOAT b)
- {
- return IEEESPMul (a, b);
- }
- #endif
-
- #if defined(L__subdf3) || defined(ALL)
- double __subdf3 (double a, double b)
- {
- return IEEEDPSub (a, b);
- }
- #endif
-
- #if defined(L__subsf3) || defined(ALL)
- SFVALUE __subsf3 (FLOAT a, FLOAT b)
- {
- return IEEESPSub (a, b);
- }
- #endif
-
- #if defined(L__truncdfsf2) || defined(ALL)
- SFVALUE __truncdfsf2 (double a)
- {
- return IEEEDPTieee(a);
- }
- #endif
-
- #endif /* __HAVE_68881__ */
-